﻿Public Class EMyExplainPlanException
    Inherits Exception
    Public Sub New()
        MyBase.New()
    End Sub
    Public Sub New(ByVal Msg As String)
        MyBase.New(Msg)
    End Sub
    Public Sub New(ByVal Msg As String, ByVal ex As Exception)
        MyBase.New(Msg, ex)
    End Sub
End Class

Public Class TMyExplainPlan
    Implements System.IDisposable

    Private _Query As New TMyQuery
    Private _SQL As String
    Private _List As New List(Of TMyExplainItem)
    Private _DataTable As DataTable

    Public Sub New(ByVal AConnection As TMySession)
        _Query.Session = AConnection
    End Sub
    Public Property SQL() As String
        Get
            Return _SQL
        End Get
        Set(ByVal value As String)
            _SQL = value
        End Set
    End Property
    Public ReadOnly Property Count() As Integer
        Get
            Return _List.Count
        End Get
    End Property
    Default Public ReadOnly Property Items(ByVal Index As Integer) As TMyExplainItem
        Get
            Return _List(Index)
        End Get
    End Property

    Public ReadOnly Property DataTable() As DataTable
        Get
            Return _DataTable
        End Get
    End Property

    Public Sub Explain()
        _List.Clear()
        _Query.Clear()
        _Query.SQL.AppendLine("explain " & _SQL)
        Try
            _Query.Execute()
            _DataTable = _Query.DataSet.Tables(0).Copy
            While Not _Query.Eof
                Dim item As New TMyExplainItem
                item._ID = _Query.FieldAsInteger("id")
                item._SelectType = _Query.FieldAsString("select_type")
                item._Table = _Query.FieldAsString("table")
                item._Type = _Query.FieldAsString("type")
                item._PossibleKeys = _Query.FieldAsString("possible_keys")
                item._Key = _Query.FieldAsString("key")
                item._KeyLen = _Query.FieldAsInteger("key_len")
                item._Ref = _Query.FieldAsString("ref")
                item._Rows = _Query.FieldAsInteger("rows")
                item._Extra = _Query.FieldAsString("extra")
                _List.Add(item)
                _Query.MoveNext()
            End While
            _Query.Close()
        Catch ex As Exception
            Throw New EMyExplainPlanException(ex.Message, ex)
        End Try
    End Sub

    Private disposedValue As Boolean = False        ' 重複する呼び出しを検出するには

    ' IDisposable
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: 他の状態を解放します (マネージ オブジェクト)。
            End If
            _Query.Close()
            _Query.Dispose()
            _List.Clear()
            _List = Nothing
            _DataTable = Nothing
            If _DataTable IsNot Nothing Then
                _DataTable.Dispose()
            End If
            ' TODO: ユーザー独自の状態を解放します (アンマネージ オブジェクト)。
            ' TODO: 大きなフィールドを null に設定します。
        End If
        Me.disposedValue = True
    End Sub

#Region " IDisposable Support "
    ' このコードは、破棄可能なパターンを正しく実装できるように Visual Basic によって追加されました。
    Public Sub Dispose() Implements IDisposable.Dispose
        ' このコードを変更しないでください。クリーンアップ コードを上の Dispose(ByVal disposing As Boolean) に記述します。
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

End Class
